Spring Cloud 进阶之Ribbon和Feign(负载均衡)

Ribbon 负载均衡

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端,负载均衡的工具;

Ribbon 核心组件IRule

根据特定算法,从服务列表中选取一个要访问的服务:

  • RoundRobinRule:轮询
  • RandomRule:随机
  • AvailabilityFilteringRule: 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,以及并发的连接数量
    超过阈值的服务,然后对剩余的服务列表按照轮询策略进行访问;
  • WeightedResponseTimeRule: 根据平均响应时间计算所有服务的权重,响应时间越快,服务权重越大,被选中的机率越高;
    刚启动时,如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够时,会切换到WeightedResponseTimeRule
  • RetryRule: 先按照RoundRobinRule的策略获取服务,如果获取服务失败,则在指定时间内会进行重试,获取可用的服务;
  • BestAvailableRule: 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务;
  • ZoneAvoidanceRule: 默认规则,复合判断server所在区域的性能和server的可用性选择服务器;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// ConfigBean 添加新注解 @LoadBalanced, 用于加入 Ribbon 配置
@Configuration
public class ConfigBean {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

@Configuration
public class ConfigBean {

@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}

@Bean
public IRule myRule() {
return new RoundRobinRule(); // 显式的指定使用轮询算法
}
}


// 修改主启动类
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name="MICROSERVICECLOUD-DEPT", configuration=MySelfRule.class) // 自定义Ribbon配置类
public class DeptConsumer80_App {

public static void main(String[] args) {

SpringApplication.run(DeptConsumer80_App.class, args);
}

}


// com.noodles.myrule
// 自定义Robbin规则类
@Configuration
public class MySelfRule{
@Bean
public IRule myRule(){
return new RandomRule(); //自定义均衡策略
}
}

Feign 负载均衡

Feign 是一个声明式WebService客户端:
使用方法: 定义一个接口,然后在上面添加注解;

  • 首先通过 @EnableFeignClients 注解开启 FeignClient 的功能。只有这个注解存在,才会在程序启动时开启 @FeignClient 注解的包扫描。
  • 根据Feign的规则实现接口,并在接口上面加上 @FeignClient 注解。
  • 程序启动后,会进行包扫描,扫描所有的@FeignClient 的注解的类,并将这些信息注入 IOC容器中。
  • 当接口的方法被调用时,通过JDK的代理来生成具体的 RequestTemplate 模板对象。
  • 根据 RequestTemplate 再生成 Http 请求的 Request 对象。
  • Request 对象交给 Client 去处理,其中 Client 的网络请求框架可以是 HTTPURLConnection、HttpClient 和 OkHttp。
  • 最后Client被封装到LoadBalanceClient类,这个类结合类 Ribbon 做到了负载均衡。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 新建DeptClientService接口,并新增注解@FeignClient,来指定调用哪个服务
@FeignClient(value="MICROSERVICECLOUD-DEPT")
public interface DeptClientService {

@RequestMapping(value="/dept/get/{id}", method= RequestMethod.GET)
public Dept get(@PathVariable("id") long id);

@RequestMapping(value="/dept/list", method= RequestMethod.GET)
public List<Dept> list();

@RequestMapping(value="/dept/add", method= RequestMethod.POST)
public boolean add(Dept dept);
}

// microservice-consumer-dept-feign 工程修改Controller
@RestController
public class DeptController_Consumer {

//用于服务调用
@Autowired
private DeptClientService service;

@RequestMapping(value="/consumer/dept/get/{id}")
public Dept get(@PathVariable("id") Long id) {
return this.service.get(id);
}

@RequestMapping(value="/consumer/dept/list")
public List<Dept> list(){
return this.service.list();
}

@RequestMapping(value="/consumer/dept/add")
public Object add(Dept dept) {
return this.service.add(dept);
}
}